﻿#include<iostream>
using namespace std;

//class A
//{
//	public :
//	virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//	virtual void test() { func(); }
//};
//class B : public A
//{
//	public :
//	void func(int val = 0) { std::cout << "B->" << val << std::endl; }
//};
//int main(int argc, char* argv[])
//{
//	B* p = new B;
//	p->func();//这里不构成多态，因为传的是子类的指针，调用子类的func函数
//	p->test();//这里构成多态，因为test虚函数中基类的this指针指向子类，调用的子类的func函数
//	          //但多态中，子类虚函数完成的是对父类虚函数的重写，重写的是函数的实现，函数头不重写
//              //注意：继承中绝不重写定义继承而来的缺省值
//	return 0;
//
//}



// 析构函数的重写

//class A
//{
//	public :
//	virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//class B : public A {
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//
//// 只有派⽣类B的析构函数重写了A的析构函数，下⾯的delete对象调⽤析构函数，才能
////构成多态，才能保证p1和p2指向的对象正确的调⽤析构函数。
//int main()
//{
//	//delete->析构函数 + operator delete构成
//	//派生类的析构函数结束后会自动调用父类的析构函数，先子后父的顺序
//	A* p1 = new A;
//	A* p2 = new B;
//	delete p1;
//	delete p2;
//	return 0;
//}


//纯虚函数和抽象类
//class Car
//{
//	public :
//	virtual void Drive() = 0;
//};
//class Benz :public Car
//{
//	public :
//	virtual void Drive()
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//
//class BMW :public Car
//{
//	public :
//	virtual void Drive()
//	{
//		cout << "BMW-操控" << endl;
//	}
//};
//int main()
//{
//	// 编译报错：error C2259: “Car”: ⽆法实例化抽象类
//	//Car car;
//	//父类的指针指向子类，实现多态
//	Car* pBenz = new Benz; 
//	pBenz->Drive();
//	Car* pBMW = new BMW;
//	pBMW->Drive();
//	return 0;
//}
//


//int main()
//{
//
//	int i = 42, * p = &i, & r = i;
//	decltype(i) s = 20;
//	decltype(r) m = i;
//	cout << typeid(i).name() << endl;
//	cout << typeid(*p).name() << endl;
//	cout << typeid(r).name() << endl;
//	cout << typeid(s).name() << endl;
//	cout << typeid(m).name() << endl;
//	return 0;
//}


//虚函数表本质上是一个函数指针数组，存放的是类中所有虚函数的地址，通过一个虚表指针维护它
class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
	virtual void BuyTicket() { cout << "买票-打折" << endl; }
};
class Soldier : public Person {
public:
	virtual void BuyTicket() { cout << "买票-优先" << endl; }
};
void Func(Person* ptr)
{
	// 这⾥可以看到虽然都是Person指针Ptr在调⽤BuyTicket
	// 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
	ptr->BuyTicket();
}

int main()
{
	// 其次多态不仅仅发⽣在派⽣类对象之间，多个派⽣类继承基类，重写虚函数后
	// 多态也会发⽣在多个派⽣类之间。
	Person ps;
	Student st;
	Soldier sr;
	Func(&ps);
	Func(&st);
	Func(&sr);
	return 0;
}
